using MediatR;
using Medical.Domain;
using Medical.Infrastructrue.Interfaces;
using Medical.Infrastructrue.Utils;
using Medical.ReadApi.Appcontext.Command;
using Medical.ReadApi.Dto;
using Microsoft.EntityFrameworkCore;

namespace Medical.ReadApi.Appcontext.CommandHandler
{
	public class LoginUserQueryHandler : IRequestHandler<LoginUserQuery, LoginResponseDto>
	{
		private readonly IBaseRepository<User> _userRepo;
		private readonly IBaseRepository<UserRole> _userRoleRepo;
		private readonly IBaseRepository<Role> _roleRepo;
		private readonly IBaseRepository<RolePermission> _rolePermissionRepo;
		private readonly IBaseRepository<Permission> _permissionRepo;

		public LoginUserQueryHandler(
			IBaseRepository<User> userRepo,
			IBaseRepository<UserRole> userRoleRepo,
			IBaseRepository<Role> roleRepo,
			IBaseRepository<RolePermission> rolePermissionRepo,
			IBaseRepository<Permission> permissionRepo)
		{
			_userRepo = userRepo;
			_userRoleRepo = userRoleRepo;
			_roleRepo = roleRepo;
			_rolePermissionRepo = rolePermissionRepo;
			_permissionRepo = permissionRepo;
		}

		public async Task<LoginResponseDto> Handle(LoginUserQuery request, CancellationToken cancellationToken)
		{
			// 查找用户
			var user = await _userRepo.GetModel(x => 
				x.UserName == request.UserName && !x.IsDeleted && x.IsActive);
			
			if (user == null)
			{
				throw new Exception("用户名或密码错误");
			}

			// 验证密码
			if (!PasswordHasher.VerifyPassword(request.Password, user.PasswordHash))
			{
				throw new Exception("用户名或密码错误");
			}

			// 更新登录信息
			user.LastLoginAt = DateTime.Now;
			user.LastLoginIp = request.LoginIp;
			user.UpdatedAt = DateTime.Now;
			await _userRepo.UpdateAsync(user);

			// 获取用户角色
			var userRoleIds = _userRoleRepo.GetAll()
				.Where(x => ((UserRole)x).UserId == user.UserId)
				.Select(x => ((UserRole)x).RoleId)
				.ToList();

			var roles = new List<RoleDto>();
			var permissions = new List<PermissionDto>();

			if (userRoleIds.Any())
			{
				// 获取角色信息
				roles = await _roleRepo.GetAll()
					.Where(x => userRoleIds.Contains(x.RoleId) && x.IsActive)
					.Select(r => new RoleDto
					{
						RoleId = r.RoleId,
						Name = r.Name,
						Description = r.Description,
						IsActive = r.IsActive,
						CreatedAt = r.CreatedAt,
						UpdatedAt = r.UpdatedAt
					})
					.ToListAsync(cancellationToken);

				// 获取角色权限ID
				var permissionIds = _rolePermissionRepo.GetAll()
					.Where(x => userRoleIds.Contains(((RolePermission)x).RoleId))
					.Select(x => ((RolePermission)x).PermissionId)
					.Distinct()
					.ToList();

				// 获取权限信息
				if (permissionIds.Any())
				{
					permissions = await _permissionRepo.GetAll()
						.Where(x => permissionIds.Contains(x.PermissionId) && x.IsActive)
						.Select(p => new PermissionDto
						{
							PermissionId = p.PermissionId,
							Name = p.Name,
							Code = p.Code,
							Group = p.Group,
							Description = p.Description,
							IsMenu = p.IsMenu,
							IsActive = p.IsActive,
							CreatedAt = p.CreatedAt,
							UpdatedAt = p.UpdatedAt
						})
						.Distinct()
						.ToListAsync(cancellationToken);
				}
			}

			// 生成Token（简化版，实际应该使用JWT）
			var token = GenerateSimpleToken(user.UserId, user.UserName);

			return new LoginResponseDto
			{
				UserId = user.UserId,
				UserName = user.UserName,
				FullName = user.FullName,
				Token = token,
				ExpiresAt = DateTime.Now.AddDays(7), // Token有效期7天
				Roles = roles,
				Permissions = permissions
			};
		}

		private string GenerateSimpleToken(long userId, string userName)
		{
			// 简化的Token生成，实际应该使用JWT
			var tokenData = $"{userId}:{userName}:{DateTime.Now:yyyyMMddHHmmss}";
			var bytes = System.Text.Encoding.UTF8.GetBytes(tokenData);
			return Convert.ToBase64String(bytes);
		}
	}
}

